<template>
  <el-container>
    <el-header>
      <layout-header @switchMenu="switchMenu">
        <div slot="link" class="layout-link" v-if="isHeaderMenu">
          <div
            :class="{
              link: true,
              activeLink: item.index === menuData.currentIndex,
            }"
            ref="link"
            v-for="item in $store.getters.menu"
            :key="item.index"
            @click="toPage(item)"
          >
            <i :class="item.img" style="font-size: 26px"></i>
            <p v-text="item.name"></p>
          </div>
        </div>
      </layout-header>
    </el-header>
    <el-container class="home-container">
      <layout-side
        v-show="menuData.menu.length > 0"
        :currentActive="currentActive"
        :menuData="menuData.menu"
      ></layout-side>
      <el-main>
        <el-tabs
          class="page-tab"
          v-show="pageTabs.length > 0"
          v-model="pageTabsValue"
          type="card"
          closable
          @contextmenu.prevent.native="openContextmenu($event)"
          @tab-remove="removeTab"
          @tab-click="tabClick"
        >
          <el-tab-pane
            v-for="item in pageTabs"
            :key="item.name"
            :label="item.meta.name"
            :name="item.name"
          ></el-tab-pane>
        </el-tabs>
        <div class="page">
          <p class="page-title-p">
            <span
              class="page-title-span"
              v-text="pageDynamicItem.pageTitle"
            ></span>
            <el-button
              icon="el-icon-back"
              class="backBtn"
              v-if="pageDynamicItem.hasBackBtn"
              type="success"
              @click="backToList()"
              >返回
            </el-button>
          </p>
          <keep-alive :include="include">
            <!-- 这里是会被缓存的视图组件 -->
            <router-view v-if="$route.meta.keepAlive"></router-view>
          </keep-alive>
          <!-- 这里是不被缓存的视图组件 -->
          <router-view v-if="!$route.meta.keepAlive"></router-view>
        </div>

        <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
          <li @click="refreshSelectedTag(selectedTag)">刷新</li>
          <li @click="closeTag(selectedTag)">关闭</li>
          <li @click="closeOther">关闭其他</li>
          <li @click="closeAllTags(selectedTag)">关闭全部</li>
        </ul>
      </el-main>
    </el-container>
  </el-container>
</template>

<script>
import layoutHeader from '@/components/header'
import layoutSide from '_c/menu'

import { mapGetters } from 'vuex'

export default {
  name: 'Home',
  data () {
    return {
      // 当前所在页面
      currentActive: '',
      include: [],
      // 是否折叠
      isCollapse: false,
      pageTabsValue: '',
      isHeaderMenu: false,
      visible: false,
      top: 0,
      left: 0,
      selectedTag: ''
    }
  },
  watch: {
    $route: {
      handler (to, from) {
        if (to.name === 'redirect') return
        const pageTabs = this.$store.getters.pageTabs
        const tabIndex = pageTabs.findIndex((item) => {
          return item.name === to.name
        })
        // 页面跳转时，如果原来没有就增加一个tab页
        if (tabIndex < 0 && to.path !== '/') {
          pageTabs.push({
            name: to.name,
            path: to.fullPath,
            meta: to.meta
          })
          this.$store.commit('system/SET_PAGE_TABS', pageTabs)
        }
        this.pageTabsValue = to.name
        this.currentActive = to.path

        // 如果要 to(进入)的页面是需要 keepAlive 缓存的, 把 name push 进 include 数组中
        if (to.meta.keepAlive) {
          !this.include.includes(to.name) && this.include.push(to.name)
        }
        // 如果 要 form(离开) 的页面是 keepAlive 缓存的,
        // 再根据 deepth 来判断是前进还是后退
        // 如果是后退:
        if (from && from.meta.keepAlive && to.meta.deepth < from.meta.deepth) {
          this.clearCacheTag(from.name)
        }
      },
      immediate: true
    },
    visible (value) {
      if (value) {
        document.body.addEventListener('click', () => { this.visible = false })
      } else {
        document.body.removeEventListener('click', () => { this.visible = false })
      }
    }
  },
  components: {
    layoutHeader,
    layoutSide
  },
  computed: {
    key () {
      return this.$route.name
        ? this.$route.name + new Date().getTime()
        : this.$route.fullpath + new Date().getTime()
    },
    menuData () {
      const res = {
        menu: [],
        currentIndex: ''
      }
      const menu = this.$store.getters.menu
      if (this.isHeaderMenu) {
        let parentArr = []
        parentArr = this.$utils.findIndexArray(
          menu,
          this.$route.path,
          parentArr
        )
        if (parentArr && parentArr.length > 0) {
          res.currentIndex = parentArr[0].index
          if (parentArr[0].children) {
            res.menu = parentArr[0].children
          }
        }
      } else {
        res.menu = menu
      }
      return res
    },
    // 页面标题和返回按钮是否存在
    pageDynamicItem () {
      let item = {}
      switch (this.$route.query.pageFlag) {
        case 'edit':
          item = {
            pageTitle: '编辑',
            hasBackBtn: true
          }
          return item
        case 'view':
          item = {
            pageTitle: '详情',
            hasBackBtn: true
          }
          return item
        default:
          item = {
            pageTitle: this.$route.meta.name,
            hasBackBtn: false
          }
          return item
      }
    },
    ...mapGetters({
      pageTabs: 'pageTabs'
    })
  },
  methods: {
    getTagFullPath (tagName) {
      const pageTabs = this.$store.getters.pageTabs
      return pageTabs.find(e => e.name === tagName)
    },
    getTagIndex (tagName) {
      return this.$store.getters.pageTabs.findIndex(e => e.name === tagName)
    },
    refreshSelectedTag () {
      this.clearCacheTag(this.selectedTag)
      this.$nextTick(() => {
        this.$router.push({
          path: '/redirect' + this.getTagFullPath(this.selectedTag).path
        })
      })
    },
    closeTag () {
      this.removeTab(this.selectedTag)
    },
    closeOther () {
      const tabs = this.$store.getters.pageTabs
      const find = tabs.find((tab) => tab.name === this.selectedTag)
      this.$store.commit('system/SET_PAGE_TABS', [find])
      this.$router.push({ path: find.path })
      this.include = [this.selectedTag]
    },
    closeAllTags () {
      this.$store.commit('system/SET_PAGE_TABS', [])
      this.include = []
    },
    openContextmenu (e) { // 右键单击事件
      if (e.target.id) {
        this.selectedTag = e.target.id.split('-')[1]
        const menuMinWidth = 105
        const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
        const offsetWidth = this.$el.offsetWidth // container width
        const maxLeft = offsetWidth - menuMinWidth // left boundary
        const left = e.clientX - offsetLeft + 15 // 15: margin right

        if (left > maxLeft) {
          this.left = maxLeft
        } else {
          this.left = left
        }

        this.top = e.clientY
        this.visible = true
      }

      // this.selectedTag = tag
    },
    /**
     * 删除tab页
     * @param state 标签页
     * 2021/03/10
     */
    removeTab (targetName) {
      const tabs = this.$store.getters.pageTabs
      let activeName = this.pageTabsValue
      let activeTab
      let isMove = false
      if (activeName === targetName) {
        tabs.forEach((tab, index) => {
          if (tab.name === targetName) {
            const nextTab = tabs[index + 1] || tabs[index - 1]
            if (nextTab) {
              activeName = nextTab.name
              activeTab = nextTab
            }
          }
        })
        isMove = true
      }

      this.pageTabsValue = activeName
      const filter = tabs.filter((tab) => tab.name !== targetName)
      this.$store.commit('system/SET_PAGE_TABS', filter)

      this.clearCacheTag(targetName)
      if (isMove) {
        if (activeTab) {
          this.$router.push({ path: activeTab.path })
        } else {
          this.$router.push({ path: '/' })
        }
      }
    },
    clearCacheTag (targetName) {
      // 关闭tab时去掉页面缓存
      const index = this.include.indexOf(targetName)
      index !== -1 && this.include.splice(index, 1)
    },
    /**
     * 点击tab页跳转
     * @param tab 标签页
     * 2021/03/10
     */
    tabClick (tab) {
      const page = this.getTagFullPath(tab.name)
      this.$router.push({
        path: page.path,
        query: page.query
      })
    },
    switchMenu () {
      this.isHeaderMenu = !this.isHeaderMenu
      this.$store.commit('system/SET_IS_HEADER_Menu', this.isHeaderMenu)
    },
    toPage (item) {
      if (item.children) {
        this.toPage(item.children)
      } else if (Array.isArray(item)) {
        this.toPage(item[0])
      } else {
        this.$router.push(item.path)
      }
    },
    backToList () {
      this.$router.go(-1)
    },
    // 获取折叠事件
    getCollapse (value) {
      this.isCollapse = value
    }
  },
  created () {
    const isHeaderMenu = this.$store.getters.isHeaderMenu
    if (isHeaderMenu != null) {
      this.isHeaderMenu = isHeaderMenu
    }
  },
  async mounted () {
    await this.$store.dispatch('user/getMenu')
  }
}
</script>
<style lang="scss">
/*滚动条的宽度*/
::-webkit-scrollbar {
  width: 9px;
  height: 9px;
}

/*外层轨道。可以用display:none让其不显示，也可以添加背景图片，颜色改变显示效果*/
::-webkit-scrollbar-track {
  width: 6px;
  background-color: $--background-color-base;
  -webkit-border-radius: 2em;
  -moz-border-radius: 2em;
  border-radius: 2em;
}

/*滚动条的设置*/

::-webkit-scrollbar-thumb {
  background-color: $--color-primary;
  background-clip: padding-box;
  min-height: 1px;
  -webkit-border-radius: 2em;
  -moz-border-radius: 2em;
  border-radius: 2em;
}

/*滚动条移上去的背景*/

::-webkit-scrollbar-thumb:hover {
  background-color: $--color-primary-light-3;
}

/*折叠菜单时隐藏 slot="title" 的 > 和 span 标签*/
.el-menu--collapse > .el-menu-item .el-submenu__icon-arrow,
.el-menu--collapse
  > div
  > div
  > .el-submenu
  > .el-submenu__title
  .el-submenu__icon-arrow {
  display: none;
}

.el-menu--collapse > .el-menu-item .el-submenu__icon-arrow,
.el-menu--collapse > div > div > .el-submenu > .el-submenu__title span {
  display: none;
}
.contextmenu {
  margin: 0;
  background: #fff;
  z-index: 3000;
  position: absolute;
  list-style-type: none;
  padding: 5px 0;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 400;
  color: #333;
  box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
  li {
    margin: 0;
    padding: 7px 16px;
    cursor: pointer;
    &:hover {
      background: #eee;
    }
  }
}
.el-container {
  height: 100vh;

  .el-main {
    //background: #f5f5f5 ;
    background: $--background-color-base;
    width: 1px;

    //> div:nth-child(1) {
    //  background: $--color-white;
    //  min-height: calc(100% - 10px);
    //  padding: 5px 10px;
    //  display: flex;
    //  flex-direction: column;
    //}
    > .page {
      background: $--color-white;
      height: calc(100% - 21px - 41px);
      padding: 10px 15px;
      display: flex;
      flex-direction: column;
      border: 1px solid #e4e7ed;
      border-top: none;
      overflow: auto;
    }

    > .page-tab {
      height: 41px;

      .el-tabs__header {
        margin: 0;
      }

      .el-tabs__item.is-active {
        background: $--color-white;
      }
    }
  }

  .layout-link {
    display: flex;
    justify-content: flex-start;
    width: calc(100% - 390px - 90px);
    height: 100%;
    margin-left: 65px;

    .link {
      color: $--color-white;
      width: 105px;
      height: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      border-radius: 6px;
      cursor: pointer;
      border: none;

      p {
        margin-top: 5px;
      }

      i {
        transition: transform 0.5s ease-out;
      }
    }

    .link:hover i {
      -webkit-transform: rotateZ(360deg);
      -moz-transform: rotateZ(360deg);
      -o-transform: rotateZ(360deg);
      -ms-transform: rotateZ(360deg);
      transform: rotateZ(360deg);
    }

    .activeLink {
      background: $--color-primary-light-3;
    }
  }

  .el-header {
    /*box-shadow: 1px 1px 5px 0 #ccc;*/
    background: $--color-primary;
  }

  .page-title-p {
    padding: 15px 0 20px 0;
    font-weight: bolder;
  }

  .page-title-span {
    position: relative;
    padding: 0 10px;
    border-left: 5px solid $--color-primary;
    font-size: 18px;
  }

  .page-title-span:after {
    position: absolute;
    width: 100%;
    height: 2px;
    content: "";
    top: 25px;
    left: 0;
    /*background: #ff5000;*/
    background: transparent;
  }

  .backBtn {
    float: right;
  }
}

.home-container {
  height: calc(100% - 60px) !important;
}
</style>
